package cn.hinglo.baseservice.interceptors;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;


/**
 * @author HingLo
 * @createTime: 2018/5/22
 * @description: 所有拦截的父类
 */
public abstract class BaseInterceptor implements HandlerInterceptor {

    private static final String OPTIONS = "OPTIONS";

    /**
     * 忽略拦截的注解集合
     */
    protected Set<Class> annotationList = new HashSet<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 若果是option请求，就直接返回响应了
        if (OPTIONS.equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }

        HandlerMethod handlerMethod = null;
        if (handler instanceof HandlerMethod) {
            handlerMethod = (HandlerMethod) handler;
        }
        // 如果有IgnoreToken注解，就不用拦截 直接返回就好了
        if (handlerMethod != null && isAnnotation(handlerMethod)) {
            return true;
        }
        return this.preHandle(request, response, handler, handlerMethod);
    }


    /**
     * 检测是否有制定的注解,如果有指定的忽略注解,就不执行拦截器
     *
     * @param handlerMethod handlerMethod
     * @return 返回结果,
     */
    private boolean isAnnotation(HandlerMethod handlerMethod) {
        return handlerMethod.getMethodAnnotation(ignoreAnnotation()) != null;
    }

    /***
     * 子类返回忽略的注解
     * @return 返回湖绿注解
     */
    public abstract Class<? extends Annotation> ignoreAnnotation();

    /***
     * 拦截器具体的实现方法
     *
     * @param request 请求对象
     * @param response 响应流对象
     * @param handler Object对象
     * @param handlerMethod handlerMethod 对象
     * @return 是否通过
     * @throws Exception ex
     */
    public abstract boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler, HandlerMethod handlerMethod)
            throws Exception;


}
